package com.atguigu.config;

import com.atguigu.bean.Person;
import com.atguigu.service.BookService;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;


/**  老师记的：
 * //@ComponentScan  value:指定要扫描的包
 * //excludeFilters = Filter[] ：指定扫描的时候按照什么规则排除那些组件
 * //includeFilters = Filter[] ：指定扫描的时候只需要包含哪些组件
 * //FilterType.ANNOTATION：按照注解
 * //FilterType.ASSIGNABLE_TYPE：按照给定的类型；
 * //FilterType.ASPECTJ：使用ASPECTJ表达式  ：  不常用
 * //FilterType.REGEX：使用正则指定
 * //FilterType.CUSTOM：使用自定义规则 ： 重点看看
 */

//配置类==配置文件
@Configuration    //这个注解告诉spring这是一个配置类
//@ComponentScan  value是指定要扫描的包
//excludeFilters = Filter[]。excludeFilters是一个Filter数组，这个Filter也是一个注解。
// excludeFilters既然是数组，使用的时候首先搞个大括号，然后再写Filter注解。
//那Filter注解怎么写？ 点进去看，可以选要排除的规则，比如你是按类排除，还是按注解排除，还是按正则表达式排除 ，还是自定义排除 等
/*@ComponentScan(value = "com.atguigu",excludeFilters = {
        //按注解排除，排除controller和service注解下的所有bean，注意这个classes也是数组，所以使用的时候首先也搞个大括号
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
})*/
/*@ComponentScan(value = "com.atguigu",includeFilters = {
        //这里是只包含
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})  //只要Controller注解的类
},useDefaultFilters = false)*/

//excludeFilters是排除什么注解，而includeFilters是只包含什么样的注解。
//而用 includeFilters 的时候，就必须要把useDefaultFilters设为false、意思是禁用掉默认的过滤规则，
// 因为默认的过滤规则=true(意思是加载所有)，就是扫描所有的(@Controller、@Service、@Repository，@Component)、你都加载所有了，includeFilters只包含还有个卵用啊？


//另外值得注意的是：@ComponentScan如果是JDK1.8，那么还是@Repeatable(ComponentScans.class)的。。。就可以多写几次@ComponentScan。。。
//如果不是JDK1.8 那就不能重复写撒，不过也没事，可以用@ComponentScans，它的value是一个ComponentScan数组，它里面可以写多个@ComponentScan并用逗号隔开，效果是一样的。
@ComponentScans(value = {
        @ComponentScan(value = "com.atguigu",includeFilters = {
                //按注解排除，排除controller和service注解下的所有bean
                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
        },useDefaultFilters = false),
        @ComponentScan(value = "com.atguigu",includeFilters = {
                //按注解排除，排除controller和service注解下的所有bean
                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
        },useDefaultFilters = false)
})


/**
 * 再看下  ASSIGNABLE_TYPE
 */
@ComponentScan(value = "com.atguigu",includeFilters = {
        //这里是只包含
        /*@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),  //按照注解：  只要 Controller 注解的类
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}), //按照明确的类型：  BookService这个类型的就会被放到容器里，不管是子类 还是 实现类  */
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}) // 过滤规则就是 MyTypeFilter 返回的 true 或 false 撒、   com.atguigu扫描路径下的每一个类都会进到 MyTypeFilter 里
},useDefaultFilters = false)

public class MainConfig {

    //给容器注册一个bean，类型是返回值的类型，id默认是用方法名作为bean的id、
    // 当然用value值也可以当作bean的id，而且用value值的优先级要高于方法名
    @Bean(value = "person01") //用bean注解把实例注册到IOC容器中
    public Person person(){
        return new Person("lisi",20);
    }



}
